﻿using System;
using System.Collections.Generic;
using System.Text;

namespace SXICE.Core.Models
{
    /// <summary>
    /// 返回结果
    /// 当Success为false时就是失败，ErrorCode会大于0，ErrorMessage会有具体的错误消息
    /// 当Success为true时就表示成功，Result就是结果数据，但是对于Result类型为bool的数据则需要判断Success和Result都为true才成功
    /// </summary>
    public class ReturnResult : ICloneable
    {
        public ReturnResult() { }

        public ReturnResult(int errorCode, string errorMessage)
        {
            this.ErrorCode = errorCode;
            this.ErrorMessage = errorMessage;
            this.Success = false;
        }

        /// <summary>
        /// 具体错误码
        /// </summary>
        public int ErrorCode { set; get; }

        /// <summary>
        /// 错误消息
        /// </summary>
        public string ErrorMessage { set; get; }

        /// <summary>
        /// 是否成功
        /// </summary>
        public virtual bool Success { set; get; } = true;

        /// <summary>
        /// 原型
        /// </summary>
        private static readonly ReturnResult prototype = new ReturnResult();

        /// <summary>
        /// 获取成功对象
        /// </summary>
        /// <returns></returns>
        public static ReturnResult GetResult()
        {
            var proto = (ReturnResult)prototype.Clone();
            proto.Success = true;
            return proto;
        }

        /// <summary>
        /// 获取结果
        /// </summary>
        /// <param name="errorCode">错误码</param>
        /// <param name="errorMessage">错误消息</param>
        /// <returns>结果</returns>
        public static ReturnResult GetResult(int errorCode, string errorMessage)
        {
            var proto = (ReturnResult)prototype.Clone();
            proto.ErrorCode = errorCode;
            proto.ErrorMessage = errorMessage;
            proto.Success = false;
            return proto;
        }

        /// <summary>
        /// 克隆
        /// </summary>
        /// <returns>结果</returns>
        public object Clone()
        {
            return MemberwiseClone();
        }
    }

    /// <summary>
    /// 返回结果
    /// 当Success为false时就是失败，ErrorCode会大于0，ErrorMessage会有具体的错误消息
    /// 当Success为true时就表示成功，Result就是结果数据，但是对于Result类型为bool的数据则需要判断Success和Result都为true才成功
    /// </summary>
    /// <typeparam name="TResult">返回数据类型</typeparam>
    public class ReturnResult<TResult> : ReturnResult
    {
        public ReturnResult() : base() { }

        public ReturnResult(TResult result)
        {
            this.Result = result;
        }

        public ReturnResult(int errorCode, string errorMessage) : base(errorCode, errorMessage) { }

        /// <summary> 
        /// 原型
        /// </summary>
        private static readonly ReturnResult<TResult> prototype = new ReturnResult<TResult>();

        /// <summary>
        /// 结果
        /// </summary>
        public virtual TResult Result { set; get; }

        /// <summary>
        /// 获取结果(成功）
        /// </summary>
        /// <param name="result">对象</param>
        /// <returns>结果</returns>
        public static ReturnResult<TResult> GetResult(TResult result)
        {
            var proto = (ReturnResult<TResult>)prototype.Clone();
            proto.Success = true;
            proto.Result = result;
            return proto;
        }

        /// <summary>
        /// 获取结果
        /// </summary>
        /// <param name="errorCode">错误码</param>
        /// <param name="errorMessage">错误消息</param>
        /// <returns>结果</returns>
        public static ReturnResult<TResult> GetResult(int errorCode, string errorMessage)
        {
            var proto = (ReturnResult<TResult>)prototype.Clone();
            proto.ErrorCode = errorCode;
            proto.ErrorMessage = errorMessage;
            proto.Success = false;
            return proto;
        }
    }

    /// <summary>
    /// 具体错误码
    /// </summary>
    public enum ErrorCode
    {
        /// <summary>
        /// 实体验证失败
        /// </summary>
        MODEL_ERROR = 100,
        /// <summary>
        /// 内部服务器异常
        /// </summary>
        INNER_EXCEPTION = 500,
        /// <summary>
        /// 空实体
        /// </summary>
        NULL_MODEL = 101
    }
}
